package boot

import (
	"encoding/json"
	"log"
	"os"

	"github.com/spf13/viper"
)

type GroupOption struct {
	// 用于向用户展示的名称
	Label string `json:"label"`

	// 在标注中实际使用的值
	Value string `json:"value"`
}

type Group struct {
	// 在标注中实际使用的组的名称
	Name string `json:"name"`

	// 用于向用户展示的名称
	Label string `json:"label"`

	// 组内的选项
	Options []GroupOption `json:"options"`
}

type InstanceSchema = []Group

type View struct {
	// 在标注中实际使用的名称
	Name string `json:"name"`

	// 用于向用户展示的名称
	Label string `json:"label"`

	Schema json.RawMessage `json:"schema"`
}

type ViewSchema = map[string]View

var (
	instanceSchema *InstanceSchema = nil
	viewSchema     *ViewSchema     = nil
)

func InitMeta() {
	instancePath := viper.GetString("meta.instance")
	if instancePath == "" {
		panic("can't get meta.instance")
	}

	instanceContent, err := os.ReadFile(instancePath)
	if err != nil {
		panic("read meta.instance definition failed:" + err.Error())
	}
	instance := []Group{}

	if err := json.Unmarshal(instanceContent, &instance); err != nil {
		panic("Unmarshal meta.instance failed:" + err.Error())
	}

	instanceSchema = &instance

	viewPath := viper.GetString("meta.view")
	if viewPath == "" {
		panic("can't get meta.view")
	}

	viewContent, err := os.ReadFile(viewPath)
	if err != nil {
		panic("read meta.view definition failed:" + err.Error())
	}
	view := []View{}
	if err := json.Unmarshal(viewContent, &view); err != nil {
		panic("Unmarshal meta.view failed:" + err.Error())
	}

	schema := map[string]View{}
	labels := map[string]View{}
	for _, v := range view {
		_, found := labels[v.Label]
		if found {
			log.Fatalf("parse meta.view failed: duplicate view label %s", v.Label)
		}
		_, found = schema[v.Name]
		if found {
			log.Fatalf("parse meta.view failed: duplicate view name %s", v.Name)
		}
		labels[v.Label] = v
		schema[v.Name] = v
	}

	viewSchema = &schema
}

func GetInstanceSchema() InstanceSchema {
	return *instanceSchema
}

func GetViewSchema() ViewSchema {
	return *viewSchema
}
